import pandas as pd
import numpy as np

def get_hourly_df(df, phi_tilde, df_cost, regimes, res):

    import numpy as np 

    # Define demand
    df["demand"] = df["dem_fos_ren"]

    # Add weights for wind and solar generation
    df["w_wind"] = df["wind"]/(df.wind.sum())
    df["w_solar"] = df["solar"]/(df.solar.sum())
    df["w_demand"] = df["demand"]/(df.demand.sum())

    # Add regime to input data frame.
    df["regime"] = ""
    df.loc[df.ratio_carb < phi_tilde, "regime"] = "low"
    df.loc[df.ratio_carb >= phi_tilde, "regime"] = "high"

    # Also merge cost into generation dataframe
    df = df.copy()
    df["year"] = df.index.map(lambda x: x.year)
    df = df.merge(df_cost, on="year", how="left").set_index(df.index)
    df["subsidy_wind_paid"] = df["subsidy_wind_mwh"]*df.wind
    df["subsidy_solar_paid"] = df["subsidy_solar_mwh"]*df.solar

    # Add carbon price
    df["pcarb"] = df.EUA_EUR_t + df.cps

    # Reduce data frame
    var_dem = ["demand", "wind", "solar","w_wind","w_solar", "w_demand","pele_uk", "pcarb",
                         "subsidy_wind_paid", "subsidy_solar_paid", "subsidy_wind_mwh", "subsidy_solar_mwh", "regime"]
    df_dem = df[var_dem].copy()

    # Add paid subsidy: weighted depending on RE production and regime
    for r in regimes:
        for re in res:
            df_dem.loc[df_dem.regime == r, "wsubsidy_%s_mwh" % re] = (df_dem.loc[df_dem.regime == r, "subsidy_%s_mwh" % re] * 
                                                              df_dem.loc[df_dem.regime == r, "w_%s" % re]
                                                             )/df_dem[df_dem.regime == r]["w_%s" % re].sum()

    # Add market value (p_ele): weighted depending on RE production and regime
    for r in regimes:
        for re in res:
            df_dem.loc[df_dem.regime==r,"wpele_%s_mwh" % re] = (df_dem.loc[df_dem.regime==r,"pele_uk"] * 
                                                              df_dem.loc[df_dem.regime==r,"w_%s" % re]
                                                             )/df_dem[df_dem.regime==r]["w_%s" % re].sum()
    return df_dem
    
    
def get_final_results(df_Q, df_dem, df_e, regimes, res, scc, df_lcoe):

# Emission offset by technology
    df_ = df_Q.copy()
    df_ = df_.merge(df_e, on="tech")
    df_["deltaE"] = df_["deltaQ"]*df_.e
    df_["deltaE_se"] = df_["deltaQ_se"]*df_.e
    df_["deltaE_se2"] = df_["deltaE_se"]**2
    df_deltaQ = df_.drop(["e"], axis=1)
    df_deltaQ.head(2)
    #df_deltaQ.to_excel(dir_results+"sensitivity_all.xlsx")
    
# Marginal emission offset
    df_deltaE = df_deltaQ.groupby(["RE", "regime", "Model"], as_index=False).agg({"deltaE": "sum", "deltaE_se2": "sum"})
    df_deltaE["deltaE_se"] = np.sqrt(df_deltaE.deltaE_se2)
    df_deltaE = df_deltaE.drop(["deltaE_se2"], axis=1)
    
# The carbon value in the electricity price is derived based on the average carbon price. 
    df_ = df_deltaE.copy()
    df_ = df_.merge(df_dem.groupby("regime", as_index=False).pcarb.mean(), on="regime")
    df_["market_carbon_rent"] = -df_.deltaE*df_.pcarb
    df_["market_carbon_rent_se"] = df_.deltaE_se*df_.pcarb
    df_deltaE = df_.copy()
    
# Marginal external benefit is the product of social cost of carbon and the marginal emission offset:
    df_deltaE["meb"] = -df_deltaE.deltaE*scc
    df_deltaE["meb_se"] = df_deltaE.deltaE_se*scc
    
# Optimal premium is the marginal external benefit net of carbon value embedded in the price:    
    df_deltaE["premium"] = df_deltaE.meb - df_deltaE.market_carbon_rent
    df_deltaE["premium_se"] = np.sqrt((df_deltaE.meb_se)**2 - (df_deltaE.market_carbon_rent_se)**2)
    
# Optimal Feed-in is weighted average of prices
    df_pele = df_dem[["wind", "solar", "pele_uk", "regime"]].copy()
    df_pele["p_wind"] = df_pele["wind"]*df_pele.pele_uk;
    df_pele["p_solar"] = df_pele["solar"]*df_pele.pele_uk;
    df_pele = df_pele.groupby("regime")[["wind", "solar", "p_wind", "p_solar"]].sum()
    df_pele.p_wind = df_pele.p_wind/df_pele.wind
    df_pele.p_solar = df_pele.p_solar/df_pele.solar
    df_pele = df_pele[["p_wind", "p_solar"]].copy()
    df_pele.columns = pd.MultiIndex.from_product([["market_income"], ['wind', "solar"]])
    df_pele.columns.names = ("var", "RE")
    df_pele = df_pele.stack().reset_index()
    
    df_deltaE_ = df_deltaE.copy()
    df_deltaE_ = df_deltaE.merge(df_pele, on=["regime", "RE"])
    df_deltaE_["operating_cost"] = df_deltaE_.market_income - df_deltaE_.market_carbon_rent
    df_deltaE_["feed_in"] = df_deltaE_["operating_cost"] + df_deltaE_.meb
    df_deltaE_[df_deltaE_.Model=="original"]
    df_deltaE = df_deltaE_.copy()
    
# Paid premium
    for re in res:
        for r in regimes:
            df_deltaE.loc[(df_deltaE.RE == re) & (df_deltaE.regime == r), 
                          "premium_paid"] = df_dem.loc[df_dem.regime == r,"wsubsidy_%s_mwh" % re].sum()

    df_deltaE["premium_paid_t"] = -df_deltaE.premium_paid/df_deltaE.deltaE 
    
# Add MAC = (LCOE - sum(P_ele*w_RE))/deltaE

    df_deltaE = df_deltaE.merge(df_lcoe, on="RE")

    for re in res:
        for r in regimes:
            df_deltaE.loc[(df_deltaE.RE==re) & (df_deltaE.regime==r), 
                          "wpele"] = df_dem.loc[df_dem.regime == r,"wpele_%s_mwh" % re].sum()

    df_deltaE["MAC"] = -(df_deltaE.lcoe - df_deltaE.wpele)/df_deltaE.deltaE
    
    return df_deltaE